package com.atguigu.lease.web.admin.service.impl;

import com.atguigu.lease.model.entity.*;
import com.atguigu.lease.model.enums.ItemType;
import com.atguigu.lease.model.enums.ReleaseStatus;
import com.atguigu.lease.web.admin.mapper.ApartmentInfoMapper;
import com.atguigu.lease.web.admin.mapper.GraphInfoMapper;
import com.atguigu.lease.web.admin.mapper.RoomInfoMapper;
import com.atguigu.lease.web.admin.service.*;
import com.atguigu.lease.web.admin.vo.attr.AttrValueVo;
import com.atguigu.lease.web.admin.vo.graph.GraphVo;
import com.atguigu.lease.web.admin.vo.room.RoomDetailVo;
import com.atguigu.lease.web.admin.vo.room.RoomItemVo;
import com.atguigu.lease.web.admin.vo.room.RoomQueryVo;
import com.atguigu.lease.web.admin.vo.room.RoomSubmitVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author liubo
 * @description 针对表【room_info(房间信息表)】的数据库操作Service实现
 * @createDate 2023-07-24 15:48:00
 */
@Service
public class RoomInfoServiceImpl extends ServiceImpl<RoomInfoMapper, RoomInfo>
        implements RoomInfoService {

    @Autowired
    private RoomInfoMapper roomInfoMapper;
    @Autowired
    private ApartmentInfoMapper apartmentInfoMapper;
    @Autowired
    private GraphInfoService graphInfoService;
    @Autowired
    private AttrValueService attrValueService;
    @Autowired
    private RoomFacilityService roomFacilityService;
    @Autowired
    private LabelInfoService labelInfoService;
    @Autowired
    private PaymentTypeService paymentTypeService;
    @Autowired
    private LeaseTermService leaseTermService;
    @Autowired
    private RoomAttrValueService roomAttrValueService;
    @Autowired
    private RoomLabelService roomLabelService;
    @Autowired
    private RoomPaymentTypeService roomPaymentTypeService;
    @Autowired
    private RoomLeaseTermService roomLeaseTermService;


    @Override
    public void pageRoomByQuery(IPage<RoomItemVo> page, RoomQueryVo queryVo) {
        roomInfoMapper.pageRoomItemByQuery(page, queryVo);
    }

    @Override
    public RoomDetailVo getRoomDetailById(Long id) {
        // 1、查询RoomInfo
        RoomInfo roomInfo = getById(id);
        // 2、查询房间所属公寓信息
        ApartmentInfo apartmentInfo = apartmentInfoMapper.selectById(roomInfo.getApartmentId());
        // 3、查询房间图片信息
        List<GraphInfo> graphInfoList = graphInfoService.list(new LambdaQueryWrapper<GraphInfo>().eq(GraphInfo::getItemType, ItemType.ROOM).eq(GraphInfo::getItemId, id));
        // 4、查询房间属性信息
        List<AttrValueVo> attrValueList = attrValueService.getAttrValueListById(id);
        // 5、查询房间配套信息
        List<FacilityInfo> facilityList = roomFacilityService.getRoomFacilityListById(id);
        // 6、查询房间标签信息
        List<LabelInfo> labelInfoList = labelInfoService.getLabelInfoListByRoomId(id);
        // 7、查询房间支付方式
        List<PaymentType> paymentTypeList = paymentTypeService.getPaymentTypeListByRoomId(id);
        // 8、查询房间可选租期
        List<LeaseTerm> leaseTermList = leaseTermService.getLeaseTermListByRoomId(id);

        RoomDetailVo roomDetailVo = new RoomDetailVo();
        BeanUtils.copyProperties(roomInfo, roomDetailVo);
        roomDetailVo.setApartmentInfo(apartmentInfo);
        roomDetailVo.setGraphVoList(graphInfoList.stream().map(graphInfo -> GraphVo.builder().name(graphInfo.getName()).url(graphInfo.getUrl()).build()).toList());
        roomDetailVo.setAttrValueVoList(attrValueList);
        roomDetailVo.setFacilityInfoList(facilityList);
        roomDetailVo.setLabelInfoList(labelInfoList);
        roomDetailVo.setPaymentTypeList(paymentTypeList);
        roomDetailVo.setLeaseTermList(leaseTermList);

        return roomDetailVo;
    }

    @Override
    public void saveOrUpdateRoom(RoomSubmitVo roomSubmitVo) {
        Long roomId0 = roomSubmitVo.getId();

        boolean updateFlag = roomId0 != null && roomId0 != 0;

        // 1、保存或更新RoomInfo自身的信息（insert或update roomInfo表）
        super.saveOrUpdate(roomSubmitVo);

        // 2、如果是更新，则需要先删除掉之前的关系信息
        if (updateFlag) {
            // 2-1 删除原有graphInfoList
            graphInfoService.remove(new LambdaQueryWrapper<GraphInfo>()
                    .eq(GraphInfo::getItemType, ItemType.ROOM)
                    .eq(GraphInfo::getItemId, roomId0));

            // 2-2 删除原有roomAttrValueList
            roomAttrValueService.remove(new LambdaQueryWrapper<RoomAttrValue>()
                    .eq(RoomAttrValue::getRoomId, roomId0));

            // 2-3 删除原有roomFacilityList
            roomFacilityService.remove(new LambdaQueryWrapper<RoomFacility>()
                    .eq(RoomFacility::getRoomId, roomId0));

            // 2-4 删除原有roomLabelList
            roomLabelService.remove(new LambdaQueryWrapper<RoomLabel>()
                    .eq(RoomLabel::getRoomId, roomId0));

            // 2-5 删除原有paymentTypeList
            roomPaymentTypeService.remove(new LambdaQueryWrapper<RoomPaymentType>()
                    .eq(RoomPaymentType::getRoomId, roomId0));

            // 2-6 删除原有leaseTermList
            roomLeaseTermService.remove(new LambdaQueryWrapper<RoomLeaseTerm>()
                    .eq(RoomLeaseTerm::getRoomId, roomId0));

            // 3、保存房间的信息
            Long roomId = roomSubmitVo.getId();

            // 3-1 保存新的graphInfoList
            graphInfoService.saveOrUpdateBatch(
                    roomSubmitVo.getGraphVoList().stream().map(graphVo ->
                            GraphInfo.builder()
                                    .name(graphVo.getName())
                                    .url(graphVo.getUrl())
                                    .itemType(ItemType.ROOM)
                                    .itemId(roomId)
                                    .build()
                    ).toList()
            );

            // 3-2 保存新的roomAttrValueList
            roomSubmitVo.getAttrValueIds().stream().map(attrValueId -> new RoomAttrValue(roomId, attrValueId))
                    .forEach(roomAttrValueService::saveOrUpdate);

            // 3-3 保存新的facilityInfoList
            roomSubmitVo.getFacilityInfoIds().stream().map(facilityId -> new RoomFacility(roomId, facilityId))
                    .forEach(roomFacilityService::saveOrUpdate);

            // 3-4 保存新的labelInfoList
            roomSubmitVo.getLabelInfoIds().stream().map(labelInfoIds -> new RoomLabel(roomId, labelInfoIds))
                    .forEach(roomLabelService::saveOrUpdate);

            // 3-5 保存新的paymentTypeList
            roomSubmitVo.getPaymentTypeIds().stream().map(paymentTypeIds -> new RoomPaymentType(roomId, paymentTypeIds))
                    .forEach(roomPaymentTypeService::saveOrUpdate);

            // 3-6 保存新的leaseTermList
            roomSubmitVo.getLeaseTermIds().stream().map(leaseTermIds -> new RoomLeaseTerm(roomId, leaseTermIds))
                    .forEach(roomLeaseTermService::saveOrUpdate);
        }

    }

    @Override
    public void removeRoomById(Long id) {
        // 1、删除房间本身的信息
        super.removeById(id);

        // 2、删除图片信息graphInfoList
        graphInfoService.remove(new LambdaQueryWrapper<GraphInfo>().eq(GraphInfo::getItemType, ItemType.ROOM).eq(GraphInfo::getItemId, id));

        // 3、删除房间属性信息attrValueList
        roomAttrValueService.remove(new LambdaQueryWrapper<RoomAttrValue>().eq(RoomAttrValue::getRoomId, id));

        // 4、删除配套关系信息facilityInfoList
        roomFacilityService.remove(new LambdaQueryWrapper<RoomFacility>().eq(RoomFacility::getRoomId, id));

        // 5、删除标签关系labelInfoList
        roomLabelService.remove(new LambdaQueryWrapper<RoomLabel>().eq(RoomLabel::getRoomId, id));

        // 6、删除支付关系paymentTypeList
        roomPaymentTypeService.remove(new LambdaQueryWrapper<RoomPaymentType>().eq(RoomPaymentType::getRoomId, id));

        // 7、删除可选租期leaseTermList
        roomLeaseTermService.remove(new LambdaQueryWrapper<RoomLeaseTerm>().eq(RoomLeaseTerm::getRoomId, id));
    }

    @Override
    public void updateStatus(Long id, ReleaseStatus status) {
        super.update(new LambdaUpdateWrapper<RoomInfo>().eq(RoomInfo::getId, id).set(RoomInfo::getIsRelease, status));
    }


}




